package com.basker.pisces.orm.session;

import java.util.Iterator;

import org.springframework.transaction.support.TransactionTemplate;

import com.basker.pisces.orm.data.DataSet;
import com.basker.pisces.orm.data.DataTable;
import com.basker.pisces.orm.data.meta.DataSetMeta;
import com.basker.pisces.orm.data.meta.TableMeta;
import com.basker.pisces.orm.execute.ISqlExecutor;
import com.basker.pisces.orm.parser.ISqlParser;
import com.basker.pisces.orm.statement.SelectStatement;
import com.basker.pisces.tx.TransactionHelper;

/**
 * 负责对象的读取
 *
 * @author hangwen
 */
public class DataReader {
    /**
     * sql语句解析器
     */
    private ISqlParser sqlParser;

    /**
     * sql执行器
     */
    private ISqlExecutor sqlExecutor;

    /**
     * 事务管理器
     */
    private TransactionTemplate transactionTemplate;

    public DataReader(ISqlParser sqlParser, ISqlExecutor sqlExecutor, TransactionTemplate transactionTemplate) {
        this.sqlParser = sqlParser;
        this.sqlExecutor = sqlExecutor;
        this.transactionTemplate = transactionTemplate;
    }

    /**
     * 依次读取对象的所有表，最终组装到一个dataset对象中，如果有事务上下文，读取过程会包含在事务中执行
     *
     * @param dataSetMeta
     * @param whereCondition
     * @return
     */
    public DataSet readToDataSet(DataSetMeta dataSetMeta, WhereCondition whereCondition) {
        if (this.transactionTemplate != null && this.needExplicitTransaction(dataSetMeta)) {
            boolean forUpdate = whereCondition.isForUpdate();
            this.transactionTemplate.setReadOnly(!forUpdate);

            return this.transactionTemplate.execute(status -> {
                return readToDataSet0(dataSetMeta, whereCondition);
            });
        } else {
            return this.readToDataSet0(dataSetMeta, whereCondition);
        }
    }

    /**
     * 是否需要显示开启事务:有两条以上语句需要执行的时候，即开启显示事务
     *
     * @param writeStatements
     * @return
     */
    private boolean needExplicitTransaction(DataSetMeta dataSetMeta) {
        // 已经在事务中，不需要再开启事务
        if (TransactionHelper.inTransactionScope()) {
            return false;
        }

        return dataSetMeta.getTableMetas().size() > 1;
    }

    private DataSet readToDataSet0(DataSetMeta dataSetMeta, WhereCondition whereCondition) {
        // 获取数据集元数据
        DataSet dataSet = new DataSet(dataSetMeta);
        Iterator<TableMeta> it = dataSetMeta.getTableMetas().iterator();
        // 对所有dataSetMeta集合中存在的表进行数据查询并存放到数据集中
        while (it.hasNext()) {
            TableMeta tableMeta = it.next();

            // 获取当前数据表的查询语句
            SelectStatement selectStatement = sqlParser.getSelectStatement(dataSetMeta, tableMeta, whereCondition);

            String sql = selectStatement.getSql();
            Object[] arguments = selectStatement.getArguments();
            int[] argumentTypes = selectStatement.getArgumentTypes();

            // 执行语句，填充到datatable中
            DataTable table = sqlExecutor.queryForDataTable(tableMeta, sql, arguments, argumentTypes);

            dataSet.addDataTable(table);
        }

        return dataSet;
    }
}
